// 09_common_collections.rs
// 演示 Rust 中的常见集合类型及常用操作

// 导入 HashMap 和 HashSet
use std::collections::{HashMap, HashSet};

// 将原来的 main 函数改为公共的 run 函数
pub fn run() {
    // 1. Vector
    // Vector 是一个可变长度的同类型元素的集合，在内存中连续存储
    
    // a. 创建 Vector
    let v1: Vec<i32> = Vec::new(); // 创建空 Vector，需要指定类型
    let v2 = vec![1, 2, 3, 4, 5]; // 使用宏创建包含初始值的 Vector
    
    println!("v1 是空的: {}", v1.is_empty());
    println!("v2 的内容: {:?}", v2);
    
    // b. 更新 Vector
    let mut v3 = Vec::new();
    v3.push(10);
    v3.push(20);
    v3.push(30);
    
    println!("添加元素后的 v3: {:?}", v3);
    
    // c. 读取 Vector 中的元素
    let third: &i32 = &v3[2]; // 使用索引访问，越界会导致运行时错误
    println!("v3 的第三个元素: {}", third);
    
    match v3.get(2) { // 使用 get 方法访问，返回 Option<&T>
        Some(third) => println!("v3 的第三个元素: {}", third),
        None => println!("v3 没有第三个元素"),
    }
    
    // d. 遍历 Vector
    println!("遍历 v3 中的元素:");
    for i in &v3 {
        println!("{}  ", i);
    }
    
    // e. 遍历并修改 Vector 中的元素
    println!("将 v3 中的元素翻倍:");
    for i in &mut v3 {
        *i *= 2; // 需要解引用操作符
        println!("{}  ", i);
    }
    
    println!("修改后的 v3: {:?}", v3);
    
    // f. Vector 的长度和容量
    println!("v3 的长度: {}", v3.len());
    println!("v3 的容量: {}", v3.capacity());
    
    // g. 从 Vector 中移除元素
    let popped = v3.pop(); // 移除并返回最后一个元素
    println!("从 v3 中弹出的元素: {:?}", popped);
    println!("弹出元素后的 v3: {:?}", v3);
    
    // 2. String
    // String 是 UTF-8 编码的可变字符串
    
    // a. 创建 String
    let s1 = String::new(); // 创建空 String
    let s2 = "初始字符串".to_string(); // 从字符串字面量创建
    let s3 = String::from("Hello, Rust!"); // 使用 from 方法创建
    
    println!("\ns1 是空的: {}", s1.is_empty());
    println!("s2: {}", s2);
    println!("s3: {}", s3);
    
    // b. 更新 String
    let mut s4 = String::from("Hello");
    s4.push(' '); // 添加单个字符
    s4.push_str("world!"); // 添加字符串切片
    
    println!("更新后的 s4: {}", s4);
    
    // c. 拼接字符串
    let s5 = String::from("Hello");
    let s6 = String::from("world");
    let s7 = s5 + &s6; // s5 被移动，不再有效
    
    println!("拼接后的 s7: {}", s7);
    // println!("s5: {}", s5); // 这会导致编译错误，因为 s5 已经被移动
    
    // 使用 format! 宏拼接多个字符串，不会获取所有权
    let s8 = String::from("tic");
    let s9 = String::from("tac");
    let s10 = String::from("toe");
    let s11 = format!("{}-{}-{}", s8, s9, s10);
    
    println!("使用 format! 宏拼接的字符串: {}", s11);
    println!("s8 仍然有效: {}", s8); // s8 仍然有效
    
    // d. 字符串长度
    let len = s11.len();
    println!("s11 的长度: {}", len);
    
    // e. 遍历字符串
    // 注意：Rust 的字符串不支持索引访问，因为 UTF-8 编码的原因
    let s12 = String::from("你好，世界！");
    
    println!("按字节遍历 s12:");
    for b in s12.bytes() {
        print!("{} ", b);
    }
    println!();
    
    println!("按字符遍历 s12:");
    for c in s12.chars() {
        print!("{}", c);
    }
    println!();
    
    // 3. HashMap
    // HashMap 存储键值对，需要导入 std::collections::HashMap
    
    // a. 创建 HashMap
    let mut scores = HashMap::new();
    
    // b. 插入键值对
    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Yellow"), 50);
    
    println!("\nHashMap 内容: {:?}", scores);
    
    // c. 访问 HashMap 中的值
    let team_name = String::from("Blue");
    let score = scores.get(&team_name); // 返回 Option<&V>
    
    match score {
        Some(s) => println!("Blue 队的分数: {}", s),
        None => println!("没有找到 Blue 队的分数"),
    }
    
    // d. 遍历 HashMap
    println!("遍历 HashMap:");
    for (key, value) in &scores {
        println!("{}: {}", key, value);
    }
    
    // e. 更新 HashMap
    // 覆盖已存在的值
    scores.insert(String::from("Blue"), 25);
    println!("覆盖后，Blue 队的分数: {:?}", scores.get(&String::from("Blue")));
    
    // 只在键不存在时插入
    scores.entry(String::from("Red")).or_insert(30);
    scores.entry(String::from("Blue")).or_insert(50); // 不会覆盖
    
    println!("使用 entry 方法后的 HashMap: {:?}", scores);
    
    // f. 根据旧值更新新值
    let text = "hello world wonderful world";
    let mut word_count = HashMap::new();
    
    for word in text.split_whitespace() {
        let count = word_count.entry(word).or_insert(0);
        *count += 1; // 解引用以修改值
    }
    
    println!("单词计数: {:?}", word_count);
    
    // 4. HashSet
    // HashSet 存储唯一的值
    
    // a. 创建 HashSet
    let mut books = HashSet::new();
    
    // b. 插入元素
    books.insert("The Rust Programming Language");
    books.insert("Programming Rust");
    books.insert("Rust in Action");
    books.insert("The Rust Programming Language"); // 重复元素，不会被插入
    
    println!("\nHashSet 内容: {:?}", books);
    println!("HashSet 中元素数量: {}", books.len());
    
    // c. 检查元素是否存在
    println!("HashSet 包含 'The Rust Programming Language': {}", 
             books.contains(&"The Rust Programming Language"));
    
    // d. 移除元素
    books.remove("Programming Rust");
    println!("移除元素后的 HashSet: {:?}", books);
    
    // e. 遍历 HashSet
    println!("遍历 HashSet:");
    for book in &books {
        println!("{}", book);
    }
    
    // 5. 集合操作
    let mut set_a: HashSet<i32> = vec![1, 2, 3, 4, 5].into_iter().collect();
    let set_b: HashSet<i32> = vec![3, 4, 5, 6, 7].into_iter().collect();
    
    // 交集
    let intersection: HashSet<_> = set_a.intersection(&set_b).collect();
    println!("\n集合 A 和 B 的交集: {:?}", intersection);
    
    // 并集
    let union: HashSet<_> = set_a.union(&set_b).collect();
    println!("集合 A 和 B 的并集: {:?}", union);
    
    // 差集
    let difference: HashSet<_> = set_a.difference(&set_b).collect();
    println!("集合 A 减去集合 B: {:?}", difference);
}